﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data;
using System.Web.UI;
using System.Web.UI.WebControls;
using umbraco.NodeFactory;
using umbraco.BasePages;
using umbraco.uicontrols;

namespace ExtendedWorkFlow.Pages
{

    public partial class WorkBox : umbraco.BasePages.UmbracoEnsuredPage
    {

        #region Variables

        ClientTools _ClientTools;
        DataSet _UserWorkBox;
        Node _State;
        Dictionary<int, Node> _colActions = new Dictionary<int, Node>();

        public umbraco.uicontrols.TabPage FirstTab;

        #endregion

        #region Page Loader

        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);

            // For javascript modal windows
            _ClientTools = new ClientTools(this.Page);

            this.rptWorkFlowStates.ItemCreated += new RepeaterItemEventHandler(rptWorkFlowStates_ItemCreated);
            this.rptWorkFlowStates.ItemCommand += new RepeaterCommandEventHandler(rptWorkFlowStates_ItemCommand);

            // Tab setup
            FirstTab = tabContent.NewTabPage("Workbox");
            FirstTab.Controls.Add(this.rptWorkFlowStates);
        }

        void rptWorkFlowStates_ItemCommand(object source, RepeaterCommandEventArgs e)
        {
            throw new NotImplementedException();
        }

        protected void Page_Load(object sender, EventArgs e)
        {
            if (!this.Page.IsPostBack)
                this.SetupUI();
        }

        #endregion

        #region Properties

        /// <summary>
        /// Current state node for the workbox item
        /// </summary>
        public Node State { get { return this._State; } }

        #endregion

        #region UI

        /// <summary>
        /// Update UI
        /// </summary>
        void SetupUI()
        {
            _UserWorkBox = ExtendedWorkFlow.Helpers.WorkFlowHelper.GetUserWorkBox(umbraco.helper.GetCurrentUmbracoUser());

            DataView dtvStates = new DataView(this._UserWorkBox.Tables[0]);
            DataTable tblStates = dtvStates.ToTable(true, new string[] { "stateid" });

            this.rptWorkFlowStates.DataSource = tblStates;
            this.rptWorkFlowStates.DataBind();            
        }

        #endregion

        #region Repeater Functions

        /// <summary>
        /// On item created setup state node
        /// </summary>
        public void rptWorkFlowStates_ItemCreated(object sender, RepeaterItemEventArgs e)
        {
            try
            {
                if (e.Item.DataItem != null)
                {
                    int intStateId = Convert.ToInt32(((DataRowView)e.Item.DataItem)["stateid"]);
                    this._State = new Node(intStateId);
                }
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(ex.ToString());
            }
        }

        /// <summary>
        /// On item created setup onclick confirmation for action buttons
        /// </summary>
        public void rptActions_ItemCreated(object sender, RepeaterItemEventArgs e)
        {
            try
            {
                if (e.Item.DataItem != null)
                {
                    LinkButton lnkAction = e.Item.FindControl("lnkAction") as LinkButton;
                    Node objNode = e.Item.DataItem as Node;

                    if (lnkAction != null &&
                        objNode != null)
                        lnkAction.Attributes.Add("onclick", "javascript: return confirm('Action this WorkFlow [" + objNode.Name + "]?');");
                }
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(ex.ToString());
            }
        }

        /// <summary>
        /// Get the WorkFlow id from withini child reapeater
        /// </summary>
        /// <param name="Row">Parent repeater</param>
        /// <returns>Id of the WorkFlow item</returns>
        public int GetWorkFlowId(Repeater sender)
        {
            try
            {
                Repeater objRepeater = sender as Repeater;
                RepeaterItem objRepeaterItem = objRepeater.Parent as RepeaterItem;

                return Convert.ToInt32(((DataRow)objRepeaterItem.DataItem)["id"]);
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(ex.ToString());
            }

            return 0;
        }

        /// <summary>
        /// Get all document for a state
        /// </summary>
        /// <param name="Row">DataRowView to get stateid from</param>
        /// <returns>DataRow collection of all documents in work flow state</returns>
        public DataRow[] GetDocuments(DataRowView Row)
        {
            try
            {
                int intStateId = Convert.ToInt32(Row["stateid"]);
                return this._UserWorkBox.Tables[0].Select("stateid=" + intStateId.ToString());
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(ex.ToString());
            }

            return null;
        }

        /// <summary>
        /// Get actions for a state
        /// </summary>
        /// <param name="StateId">StateId to lookup</param>
        /// <returns>Action Nodes</returns>
        public Node[] GetActions(DataRow Row)
        {
            // Action nodes
            List<Node> colActions = new List<Node>();

            try
            {

                // Loop though all nodes where permission have been explicitly set
                foreach (DataRow rowRow in this._UserWorkBox.Tables[1].Select("id=" + Row["id"]))
                {
                    int intActionId = Convert.ToInt32(rowRow["actionid"]);
                    Node objAction;

                    // Get node and use cached dictionary if already loaded
                    if (this._colActions.ContainsKey(intActionId))
                        objAction = this._colActions[intActionId];
                    else
                    {
                        objAction = new Node(intActionId);
                        this._colActions.Add(intActionId, objAction);
                    }

                    // Get action node
                    if (objAction.Id != 0)
                        if (string.Compare(objAction.NodeTypeAlias, WorkFlow.WORKFLOW_TYPE_ACTION, true) == 0)
                            colActions.Add(objAction);
                }
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(ex.ToString());
            }

            return colActions.ToArray();
        }

        /// <summary>
        /// Get url for diffrence modal window
        /// </summary>
        /// <param name="StateId">StateId to lookup</param>
        /// <returns>Action Nodes</returns>
        public string GetDiffrenceModalWindowUrl(DataRow Row)
        {
            int intDocumentId = Functions.ToInt(Row["documentid"]);
            return "javascript: UmbClientMgr.openModalWindow('/umbraco/WorkFlow/differences.aspx?id=" + intDocumentId.ToString() + "', 'Differences', true, 650, 510);";
        }
                
        /// <summary>
        /// Get the tooltip <description> for a action
        /// </summary>
        /// <param name="Row">Row node</param>
        /// <returns>string containing tooltip</returns>
        public string GetActionTooltip(Node Row)
        {
            if (Row.Properties["description"] != null)
                return Row.Properties["description"].Value;
            else
                return string.Empty;
        }

        #endregion

        #region Buttons

        public void btnAction_Click(object source, EventArgs e)
        {
            LinkButton objButton = source as LinkButton;

            // Get id's from the buttons
            int intId = Convert.ToInt32(objButton.CommandName.ToString());
            int intActionId = Convert.ToInt32(objButton.CommandArgument.ToString());

            if (intId != 0 && intActionId != 0)
            {
                // Action WorkFlow item
                WorkFlow objWorkFlow = new WorkFlow(intId);
                Node objAction = new Node(intActionId);
                bool blnCompleted = false;

                if (objWorkFlow.Id != 0 &&
                    objAction.Id != 0)
                {
                    // Check if there is a next state selected
                    if (objAction.Properties["nextState"] != null &&
                        umbraco.helper.IsNumeric(objAction.Properties["nextState"].Value))
                    {
                        // Get next state node and move to it
                        State objNextState = new State(Convert.ToInt32(objAction.Properties["nextState"].Value));
                        blnCompleted = objWorkFlow.NextState(objNextState);
                    }
                    else
                        // Move to the next state in the chronilogical order
                        blnCompleted = objWorkFlow.NextState();

                    if (blnCompleted)
                        ClientTools.ShowSpeechBubble(speechBubbleIcon.success, "WorkFlow actioned", "WorkFlow was actioned successfully.");
                    else
                        ClientTools.ShowSpeechBubble(speechBubbleIcon.error, "WorkFlow did not action", "There was a problem actioning this WorkFlow.");
                }
            }

            // Reload the UI
            this.SetupUI();
        }

        #endregion

    }

}